#region File Description
//-----------------------------------------------------------------------------
// OptionsMenuScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using Microsoft.Xna.Framework;
using Super_Wall_Breaker.Sources.Configuration;
using Super_Wall_Breaker.Sources.GameEngine;
using System;
#endregion

namespace Super_Wall_Breaker.Sources.Screens
{
    /// <summary>
    /// The options screen is brought up over the top of the main menu
    /// screen, and gives the user a chance to configure the game
    /// in various hopefully useful ways.
    /// </summary>
    class OptionsMenuScreen : MenuScreen
    {
        #region Fields

        MenuEntry playerOneEntry;
        MenuEntry playerTwoEntry;
        MenuEntry playerThreeEntry;
        MenuEntry playerFourEntry;
        MenuEntry soundMutedEntry;
        MenuEntry musicMutedEntry;
        MenuEntry timeEntry;

        PlayerEntries currentPlayerOneEntrie;
        PlayerEntries currentPlayerTwoEntrie;
        PlayerEntries currentPlayerThreeEntrie;
        PlayerEntries currentPlayerFourEntrie;
        
#if XBOX
        static PlayerEntries currentPlayerEntrie = PlayerEntries.Gamepad;
        static PlayerEntries currentPlayerTwoEntrie = PlayerEntries.Gamepad;
        static PlayerEntries currentPlayerThreeEntrie = PlayerEntries.Gamepad;
        static PlayerEntries currentPlayerFourEntrie = PlayerEntries.Gamepad;
#endif

        bool currentMusicMuted = false;
        bool currentSoundMuted = false;

        int timeIndex;
        string[] times = { "5", "4", "3", "2", "1", "Insane" };

        #endregion

        #region Initialization


        /// <summary>
        /// Initializes a new instance of the <see cref="OptionsMenuScreen"/> class.
        /// </summary>
        public OptionsMenuScreen()
            : base("Options")
        {
            //Config loading
            GameCreationConfiguration gcc = GameCreationConfiguration.GetInstance();
            currentPlayerOneEntrie = gcc.PlayerOneConfig;
            currentPlayerTwoEntrie = gcc.PlayerTwoConfig;
            currentPlayerThreeEntrie = gcc.PlayerThreeConfig;
            currentPlayerFourEntrie = gcc.PlayerFourConfig;
            currentMusicMuted = gcc.MusicMuted ? true : false;
            currentSoundMuted = gcc.SoundMuted ? true : false;

            string toFind;
            if (gcc.TotalTime == 24 * 60)
                toFind = "Insane";
            else
                toFind = gcc.TotalTime.ToString();

            timeIndex = Array.FindIndex<String>(times, s => s.Equals(toFind));

            // Create our menu entries.
            playerOneEntry = new MenuEntry(string.Empty);
            playerTwoEntry = new MenuEntry(string.Empty);
            playerThreeEntry = new MenuEntry(string.Empty);
            playerFourEntry = new MenuEntry(string.Empty);
            soundMutedEntry = new MenuEntry(string.Empty);
            musicMutedEntry = new MenuEntry(string.Empty);
            timeEntry = new MenuEntry(string.Empty);

            SetMenuEntryText();

            MenuEntry saveChanges = new MenuEntry("Save changes");

            // Hook up menu event handlers.
            playerOneEntry.Selected += PlayerOneMenuEntrySelected;
            playerTwoEntry.Selected += PlayerTwoMenuEntrySelected;
            playerThreeEntry.Selected += PlayerThreeMenuEntrySelected;
            playerFourEntry.Selected += PlayerFourMenuEntrySelected;
            soundMutedEntry.Selected += SoundMutedMenuEntrySelected;
            musicMutedEntry.Selected += MusicMutedMenuEntrySelected;
            timeEntry.Selected += TimeEntrySelected;
            saveChanges.Selected += SaveChangesSelected;

            // Add entries to the menu.
            MenuEntries.Add(playerOneEntry); 
            MenuEntries.Add(playerTwoEntry);
            MenuEntries.Add(playerThreeEntry);
            MenuEntries.Add(playerFourEntry);
            MenuEntries.Add(soundMutedEntry);
            MenuEntries.Add(musicMutedEntry);
            MenuEntries.Add(timeEntry);
            MenuEntries.Add(saveChanges);
        }


        /// <summary>
        /// Fills in the latest values for the options screen menu text.
        /// </summary>
        void SetMenuEntryText()
        {
            playerOneEntry.Text = "Player 1 : " + currentPlayerOneEntrie + (currentPlayerOneEntrie.Equals(PlayerEntries.Keyboard) ? " - RIGHT : " + GlobalConfiguration.DEFAULT_PLAYER1_RIGHT_KEY + " - LEFT : " + GlobalConfiguration.DEFAULT_PLAYER1_LEFT_KEY : "");
            playerTwoEntry.Text = "Player 2 : " + currentPlayerTwoEntrie + (currentPlayerTwoEntrie.Equals(PlayerEntries.Keyboard) ? " - RIGHT : " + GlobalConfiguration.DEFAULT_PLAYER2_RIGHT_KEY + " - LEFT : " + GlobalConfiguration.DEFAULT_PLAYER2_LEFT_KEY : "");
            playerThreeEntry.Text = "Player 3 : " + currentPlayerThreeEntrie + (currentPlayerThreeEntrie.Equals(PlayerEntries.Keyboard) ? " - RIGHT : " + GlobalConfiguration.DEFAULT_PLAYER3_RIGHT_KEY + " - LEFT : " + GlobalConfiguration.DEFAULT_PLAYER3_LEFT_KEY : "");
            playerFourEntry.Text = "Player 4 : " + currentPlayerFourEntrie + (currentPlayerFourEntrie.Equals(PlayerEntries.Keyboard) ? " - RIGHT : " + GlobalConfiguration.DEFAULT_PLAYER4_RIGHT_KEY + " - LEFT : " + GlobalConfiguration.DEFAULT_PLAYER4_LEFT_KEY : "");
            soundMutedEntry.Text = "Mute sound effects in game  : " + (currentSoundMuted ? "Yes" : "No");
            musicMutedEntry.Text = "Mute music in game: " + (currentMusicMuted ? "Yes" : "No");
            timeEntry.Text = "Game duration : " + times[timeIndex] + ((times[timeIndex].Equals("Insane") ? "" : " mn"));
        }


        #endregion

        #region Handle Input

        /// <summary>
        /// Event handler for when the Player One menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender</param>
        /// <param name="e">The event args</param>
        void PlayerOneMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {

            currentPlayerOneEntrie++;

            while(currentPlayerOneEntrie.Equals(PlayerEntries.AI) ||  currentPlayerOneEntrie.Equals(PlayerEntries.None))
                currentPlayerOneEntrie++;

            if (currentPlayerOneEntrie > PlayerEntries.None)
                currentPlayerOneEntrie = 0;
            
            SetMenuEntryText();
        }

        /// <summary>
        /// Event handler for when the Player Two menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void PlayerTwoMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {

            currentPlayerTwoEntrie++;

            if(currentPlayerTwoEntrie.Equals(PlayerEntries.None))
                currentPlayerTwoEntrie++;

            if (currentPlayerTwoEntrie > PlayerEntries.None)
                currentPlayerTwoEntrie = 0;

            SetMenuEntryText();
        }

        /// <summary>
        /// Event handler for when the Player Three menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void PlayerThreeMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            currentPlayerThreeEntrie++;

            if (currentPlayerThreeEntrie > PlayerEntries.None)
                currentPlayerThreeEntrie = 0;

            SetMenuEntryText();
        }

        /// <summary>
        /// Event handler for when the Player Four menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void PlayerFourMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            currentPlayerFourEntrie++;

            if (currentPlayerFourEntrie > PlayerEntries.None)
                currentPlayerFourEntrie = 0;

            SetMenuEntryText();
        }

        /// <summary>
        /// Event handler for when the Sound muted menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void SoundMutedMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            currentSoundMuted = !currentSoundMuted;
            SetMenuEntryText();
        }


        /// <summary>
        /// Event handler for when the Music muted menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void MusicMutedMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            currentMusicMuted = !currentMusicMuted;
            SetMenuEntryText();
        }


        /// <summary>
        /// Event handler for when the Time entry menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void TimeEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            timeIndex++;

            if (timeIndex >= times.Length)
                timeIndex = 0;

            SetMenuEntryText();
        }


        /// <summary>
        /// Event handler for when the Save changes menu entry is selected.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The <see cref="Super_Wall_Breaker.Sources.Screens.PlayerIndexEventArgs"/> instance containing the event data.</param>
        void SaveChangesSelected(object sender, PlayerIndexEventArgs e)
        {
            //Load the config choosen in the creation configuration
            GameCreationConfiguration gcc = GameCreationConfiguration.GetInstance();
            gcc.PlayerOneConfig = currentPlayerOneEntrie;
            gcc.PlayerTwoConfig = currentPlayerTwoEntrie;
            gcc.PlayerThreeConfig = currentPlayerThreeEntrie;
            gcc.PlayerFourConfig = currentPlayerFourEntrie;
            gcc.MusicMuted = currentMusicMuted;
            gcc.SoundMuted = currentSoundMuted;

            if(times[timeIndex].Equals("Insane"))
                gcc.TotalTime = 24 * 60;
            else
                gcc.TotalTime = int.Parse(times[timeIndex]);

            this.OnCancel(e.PlayerIndex);
        }

        #endregion
    }
}
